package estrutura;
import interfaces.IEstado;

import java.util.List;
import java.util.Random;

public class MiniMax {
	public static boolean parar = false;
	private Integer profundidade = Integer.MAX_VALUE;
    private Random random = new Random();
    private Integer visitados = 0;
    
    public MiniMax() {
    }
    public MiniMax(Integer profundidade) {
        this.profundidade = profundidade;
    }
    public Integer getVisitados() {
    	return visitados;
    }
    
    
    
    public double max(IEstado estadoCorrente) {
        visitados = 0;
        return valorMax(estadoCorrente, 1);
    }    
    
    

    public double valorMax(IEstado estadoCorrente, Integer profundidade) {
        
        if (profundidade > this.profundidade || estadoCorrente.isTerminal() || parar) {
            return estadoCorrente.calculaUtilidade();
        }
        
        double maximo = -10000; // Double.MIN_VALUE n�o funciona!;
        List<IEstado> estados = estadoCorrente.sucessores();
		for (IEstado sucessor : estados) {
            visitados++;
            double minSucessor = valorMin( sucessor , profundidade + 1);

            if (minSucessor > maximo || (minSucessor == maximo && random.nextBoolean())) {
                maximo = minSucessor;
                estadoCorrente.setUtilidade( maximo );
                estadoCorrente.setProxJogada( sucessor );
            }
            
        }
        return maximo;
    }
    

    public double valorMin(IEstado estadoCorrente, Integer profundidade) {
        
        if (profundidade > this.profundidade || estadoCorrente.isTerminal()|| parar) {
            return estadoCorrente.calculaUtilidade();
        }
        
        double minimo = 100000;
        List<IEstado> estados = estadoCorrente.sucessores();
		for (IEstado sucessor : estados) {;
            visitados++;
            double maxSucessor = valorMax( sucessor , profundidade + 1);
            
            if (maxSucessor < minimo || (maxSucessor == minimo && random.nextBoolean())) {
                minimo = maxSucessor;
                estadoCorrente.setUtilidade( minimo );
                estadoCorrente.setProxJogada( sucessor );
            }
		}
        return minimo;
    }
    
}

